package com.fbg.config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * @author dengguoxing
 * @date 2019/10/23
 * description  redis的配置bean
 *              market：订阅行情
 **/
@Configuration
public class RedisConfig {

    @Value("${spring.redis.mkdata-redis.host}")
    private String mkdataHost;

    @Value("${spring.redis.mkdata-redis.password}")
    private String mkdataPassword;

    @Value("${spring.redis.mkdata-redis.port}")
    private Integer mkdataPort;


    @Value("${spring.redis.redis-task-executor.core-pool-size}")
    private Integer corePoolSize;

    @Value("${spring.redis.redis-task-executor.max-pool-size}")
    private Integer maxPoolSize;

    @Value("${spring.redis.redis-task-executor.queue-capacity}")
    private Integer queueCapacity;


    //--------------------------- book redis -----------------------------//
    @Bean(name = "mkdataRedis")
    public RedisConnectionFactory mkdataRedisConnectionFactory() {
        RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
        standaloneConfiguration.setHostName(mkdataHost);
        standaloneConfiguration.setPort(mkdataPort);
        standaloneConfiguration.setPassword(mkdataPassword);
        standaloneConfiguration.setDatabase(0);
        LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(standaloneConfiguration);
        return redisConnectionFactory;
    }

    @Bean(name = "mkdataRedisStringTemplate")
    public StringRedisTemplate mkdataRedisStringTemplate(@Qualifier("mkdataRedis") RedisConnectionFactory cf) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(cf);
        return stringRedisTemplate;
    }

    @Bean(name = "mkdataRedisTemplate")
    public RedisTemplate mkdataRedisTemplate(@Qualifier("mkdataRedis") RedisConnectionFactory cf) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(cf);
        this.setSerializer(redisTemplate);
        return redisTemplate;
    }


    //--------------------------- public tunnel redis -----------------------------//
    @Value("${spring.redis.public-tunnel-redis.host}")
    private String mkTunnelHost;

    @Value("${spring.redis.public-tunnel-redis.password}")
    private String mkTunnelPassword;

    @Value("${spring.redis.public-tunnel-redis.port}")
    private Integer mkTunnelPort;


    @Primary
    @Bean(name = "mkTunnelRedis")
    public RedisConnectionFactory webRedisConnectionFactory() {
        RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();
        standaloneConfiguration.setHostName(mkTunnelHost);
        standaloneConfiguration.setPassword(mkTunnelPassword);
        standaloneConfiguration.setPort(mkTunnelPort);
        standaloneConfiguration.setDatabase(0);
        LettuceConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(standaloneConfiguration);
        return redisConnectionFactory;
    }

    @Bean(name = "mkTunnelRedisStringTemplate")
    public StringRedisTemplate mkTunnelRedisStringTemplate(@Qualifier("mkTunnelRedis") RedisConnectionFactory cf) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(cf);
        return stringRedisTemplate;
    }

    @Bean(name = "mkTunnelRedisTemplate")
    public RedisTemplate mkTunnelRedisTemplate(@Qualifier("mkTunnelRedis") RedisConnectionFactory cf) {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(cf);
        this.setSerializer(redisTemplate);
        return redisTemplate;
    }

    @Bean(name = "mkTunnelExecutor")
    public ThreadPoolTaskExecutor mkTunnelExecutor() {
        ThreadPoolTaskExecutor redisTaskExecutor = new ThreadPoolTaskExecutor();
        redisTaskExecutor.setCorePoolSize(corePoolSize);
        redisTaskExecutor.setMaxPoolSize(maxPoolSize);
        redisTaskExecutor.setQueueCapacity(queueCapacity);
        redisTaskExecutor.setThreadNamePrefix("bookContainer-thread-");
        return redisTaskExecutor;
    }


    @Bean(name = "mkTunnelContainer")
    public RedisMessageListenerContainer bookContainer(@Qualifier("mkTunnelRedis") RedisConnectionFactory cf,
                                                       @Qualifier("mkTunnelExecutor") ThreadPoolTaskExecutor taskExecutor) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(cf);
        container.setTaskExecutor(taskExecutor);
        return container;
    }


    //--------------------------- private function -----------------------------//

    private void setSerializer(RedisTemplate<String, String> template) {
        template.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    }

}
